﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef EventDispatcher_h__
#define EventDispatcher_h__

#include <memory>
#include <map>
#include <vector>
#include <windows.h>

namespace SkyEngine2d
{
	class Node;
	class EventListenerMouse;
	class InputEventListener;
	class InputEvent;
	class EventMouse;
	class EventKey;
	class UiCore;
	
	//! 输入事件分发器
	class InputEventDispatcher
	{
	public:
	
		static InputEventDispatcher * getInstance();
	
		~InputEventDispatcher();
		int  addListener(Node* target, const std::shared_ptr<InputEventListener> & listenter);
		void removeListenerAllByTarget(const Node* tagert);
		void removeListener(int id);
		void removeListenerAll();
	
	/////////////////////////////////////
		void dispatchEvent(InputEvent * e);
		void dispatchMouseEvent(HWND hwnd, UINT msg,float x, float y);
		void dispatchKeyEvent(HWND hwnd, UINT msg, WPARAM key);
		void dispatchCharterEvent(wchar_t ch);
	private:
		InputEventDispatcher();
		void resetRemoveFlag();
	private:
	
		unsigned int m_removeFlag;
	
		//template<typename T>
		struct Listener
		{
			bool isRemove;
			std::shared_ptr<InputEventListener> listener;
	
			Listener(const std::shared_ptr<InputEventListener>& listener, bool is_remove = false)
			{
				this->isRemove = is_remove;
				this->listener = listener;
			}
		};
	
		std::map<int, std::unique_ptr<Listener>> m_mouseListener;
		std::map<int, std::unique_ptr<Listener>> m_keyboardListener;
		std::map<const Node*, std::vector<int>>       m_listenerIds;
	
		bool  m_isDispatch;  /*!< 是否正在分发. */
	
		friend class InputEventListener;
	
		EventMouse * m_mouseEvent;
		EventKey   * m_keyEvent;
	
		UiCore      * m_uiCore;
	};
	
}

#endif // EventDispatcher_h__
